package com.hzya.frame.utils.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.text.SimpleDateFormat;
import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsonHelper
{
  private static final Logger LOGGER = LoggerFactory.getLogger(JsonHelper.class);
  private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
  private static final ObjectMapper mapper;

  static
  {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    mapper = new ObjectMapper();
    mapper.setDateFormat(dateFormat);
  }

  public static String convertObjectToJson(Object object) {
    try {
      return mapper.writeValueAsString(object);
    } catch (Exception e) {
      LOGGER.error("convertObjectToJson", e);
      throw new RuntimeException(e);
    }
  }

  public static Object convertJsonToObject(String content, Class klazz) {
    try {
      return mapper.readValue(content, klazz);
    } catch (Exception e) {
      LOGGER.error("convertJsonToObject", e);
      throw new RuntimeException(e); }
  }

  public static Object convertJsonToObject(String content, Class klazz, Map mapList) {
    Object object;
    try {
      object = mapper.readValue(content, klazz);

      if ((mapList != null) && (mapList.entrySet() != null)) {
        Iterator iterator = mapList.entrySet().iterator();
        while (iterator.hasNext()) {
          Map.Entry entry = (Map.Entry)iterator.next();
          if ((BeanHelper.hasField(klazz, (String)entry.getKey())) && ((
            (BeanHelper.getFieldType(klazz, (String)entry.getKey()) == List.class) || (BeanHelper.getFieldType(klazz, (String)entry.getKey()) == ArrayList.class)))) {
            List list = (List)BeanHelper.getPropertyValue((String)entry.getKey(), object);
            if ((list != null) && (list.size() > 0)) {
              List objectList = new ArrayList();
              for (int i = 0; i < list.size(); ++i)
                objectList.add(convertMapToObject((Class)entry.getValue(), (Map)list.get(i)));

              BeanHelper.setPropertyValue(object, (String)entry.getKey(), objectList);
            }
          }
        }
      }
      return object;
    } catch (Exception e) {
      LOGGER.error("convertJsonToObject", e);
      throw new RuntimeException(e);
    }
  }

  public static Object convertMapToObject(Class klazz, Map map) {
    Object object = BeanHelper.newInstance(klazz);
    if ((map != null) && (map.entrySet() != null)) {
      Iterator iterator = map.entrySet().iterator();
      while (iterator.hasNext()) {
        Map.Entry entry = (Map.Entry)iterator.next();
       }
    }
    return object;
  }

  public static List string2List(String jsonStr, String datePattern, Class class1) throws Exception {
    List resultList = Collections.EMPTY_LIST;

    String realPattern = (datePattern != null) ? datePattern : "yyyy/MM/dd HH:mm:ss";

    if ((jsonStr != null) && (!("".equals(jsonStr)))) {
      ObjectMapper om = new ObjectMapper();
      om.setDateFormat(new SimpleDateFormat(realPattern));
      resultList = (List)om.readValue(jsonStr, om.getTypeFactory().constructParametricType(List.class, new Class[] { class1 }));
    }
    return resultList;
  }

  public static String list2JsonStr(List dataList) throws Exception {
    ObjectMapper om = new ObjectMapper();
    om.writeValueAsString(dataList);
    return om.writeValueAsString(dataList);
  }

  public static <T> T json2Bean(String jsonStr, Class<T> clazz) {
    ObjectMapper om = new ObjectMapper();
    Object result = null;
    try {
      result = clazz.newInstance();
      result = om.readValue(jsonStr, clazz);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return (T) result;
  }

  /**
   * JSON 转小写
   * @param jsonObject
   * @return
   */
  public static JSONObject convertToLowerObject(JSONObject jsonObject) {
    /** 定义返回json*/
    JSONObject returnJsonObject = new JSONObject();

    Set<String> keys = jsonObject.keySet();
    keys.forEach(key ->{
      Object object = jsonObject.get(key);

      if (object.getClass().toString().endsWith("String")) {
        returnJsonObject.put(key.toLowerCase(), object);
      }
      if (object.getClass().toString().endsWith("JSONObject")) {
        returnJsonObject.put(key.toLowerCase(), convertToLowerObject((JSONObject) object));
      }
      if (object.getClass().toString().endsWith("JSONArray")) {
        returnJsonObject.put(key.toLowerCase(),transToArray(jsonObject.getJSONArray(key)));
      }
    });

    return returnJsonObject;
  }

  /**
   * JSON 转大写
   * @param jsonObject
   * @return
   */
  public static JSONObject convertUpperCaseObject(JSONObject jsonObject) {
    /** 定义返回json*/
    JSONObject returnJsonObject = new JSONObject();

    Set<String> keys = jsonObject.keySet();
    keys.forEach(key ->{
      Object object = jsonObject.get(key);

      if (object.getClass().toString().endsWith("String")) {
        returnJsonObject.put(key.toUpperCase(), object);
      }
      if (object.getClass().toString().endsWith("JSONObject")) {
        returnJsonObject.put(key.toUpperCase(), convertToLowerObject((JSONObject) object));
      }
      if (object.getClass().toString().endsWith("JSONArray")) {
        returnJsonObject.put(key.toUpperCase(),transToArray(jsonObject.getJSONArray(key)));
      }
    });

    return returnJsonObject;
  }

  /**
   * JSONArray转大写
   * @param jsonArray
   * @return
   */
  public static JSONArray transToArray(JSONArray jsonArray) {
    /**  定义返回*/
    JSONArray rturnJsonArray = new JSONArray();
    jsonArray.forEach(jsonObj ->{
      Object jArray = jsonObj;
      if (jArray.getClass().toString().endsWith("JSONObject")) {
        rturnJsonArray.add(convertUpperCaseObject((JSONObject) jArray));
      }
      if (jArray.getClass().toString().endsWith("JSONArray")) {
        rturnJsonArray.add(transToArray((JSONArray) jArray));
      }
    });

    return rturnJsonArray;
  }

}